home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / perl / msds-prl / ptchds19.zoo / subproc_c < prev    next >
Text File  |  1992-02-23  |  6KB  |  239 lines

  1. MS-DOS patches to perl.
  2. Apply this patch to the standard perl source, version 4, patch level 19,
  3. using "patch -p."  Do this in the root directory of the perl source
  4. distribution.
  5.  
  6. You can cat all these patches together and pipe the output to patch -p.
  7.  
  8. Len Reed
  9. Holos Software, Inc.
  10. ..!gatech!holos0!lbr
  11. holos0!lbr@gatech.edu
  12. --------------------------------------
  13. *** msdos/subproc.c.old    Sun Feb 23 08:48:16 1992
  14. --- msdos/subproc.c    Thu Nov 14 08:56:40 1991
  15. ***************
  16. *** 0 ****
  17. --- 1,221 ----
  18. + /* RCS      -- $Header: c:/usr/lbr/perl/RCS/subproc.c 1.1 90/10/15 15:14:55 lbr Exp $
  19. + -- SYNOPSIS -- Subprocess control for perl.exe: MS-DOS perl.
  20. + -- 
  21. + -- DESCRIPTION
  22. + --    Interface between programs that want to call system(), etc.,
  23. + --    and the swapping spawnv program.
  24. + --    This code was written for Microsoft C 6.0, but should be
  25. + --    nearly portable across modern MS-DOS compilers.  ANSI
  26. + --    must be understood, and the far keyword must work.
  27. + --
  28. + -- LOG
  29. + --     $Log:    subproc.c $
  30. +  * Revision 1.1  90/10/15  15:14:55  lbr
  31. +  * Initial revision
  32. +  * 
  33. +  * 
  34. + */
  35. + #include <stdlib.h>
  36. + #include <process.h>
  37. + #include <string.h>
  38. + #include <signal.h>
  39. + #include "EXTERN.h"
  40. + #include "perl.h"
  41. + static lookat_env(void);    /* interrogate environment for subshell */
  42. + static char *shell;        /* full path name of $SHELL or $COMSPEC */
  43. + static char *comspec;        /* full path name of $COMSPEC */
  44. + static char *metas;        /* list of chars that are metachars to shell */
  45. + static char *slashc;        /* usually "/c" or "-c", for running subshell */
  46. + char *DirSepStr;        /* what to put between path elements */
  47. + static unsigned short unix_status(unsigned short);
  48. + #ifdef MKS_SUPPORT
  49. + static int mksargs;        /* true if MKSARGS in environ */
  50. + extern char com_slashc[];    /* -c or /c for command.com: set at
  51. +                    startup by inspecting switch char.
  52. +                 */
  53. + #else
  54. + #define mksargs 0
  55. + static char com_slashc[] = "/c";
  56. + #endif
  57. + /* Get value from environment.  Treat null strings as unfound */
  58. + static char *getenv_or_null(char *var)
  59. + {
  60. +     char *rval = getenv(var);
  61. +     if (rval && strcmp(rval,"") == 0)
  62. +         rval = NULL;
  63. +     return rval;
  64. + }
  65. + /* Find defaults from the environment.  Done each time we need them, rather
  66. +    than at startup, so that perl script can change them dynamically.
  67. + */
  68. + static lookat_env(void)
  69. + {
  70. +     shell = getenv_or_null("SHELL");
  71. +     comspec = getenv_or_null("COMSPEC");
  72. +     metas = getenv_or_null("METACHAR");
  73. +     slashc = getenv_or_null("SLASHC");
  74. +     DirSepStr = getenv_or_null("DIRSEP");
  75. + #ifdef MKS_SUPPORT
  76. +     mksargs = getenv("MKSARGS") != NULL;
  77. + #endif
  78. +     if (comspec == NULL)
  79. +     comspec = "\\command.com";
  80. +     if (shell == NULL) {
  81. +         shell = comspec;
  82. +     if (metas == NULL)
  83. +         metas = "|<>";    /* command.com list default */
  84. +     if (DirSepStr == NULL)
  85. +         DirSepStr = "\\";
  86. +     if (slashc == NULL)
  87. +         slashc = com_slashc;    /* contains default switch char */
  88. +     }
  89. +     else {
  90. +     if (metas == NULL)
  91. +         metas = KSH_META_CHARS;      /* Korn shell list default */
  92. +     if (DirSepStr == NULL)
  93. +         DirSepStr = mksargs ? "/" : "\\";
  94. +     if (slashc == NULL)    /* MKS shell needs -e to pass back error code */
  95. +         slashc = mksargs ? "-ce" : "-c";
  96. +     }
  97. + }
  98. + /*
  99. +  * The following code is based on the do_exec and do_aexec functions
  100. +  * in file doio.c
  101. +  */
  102. + int
  103. + do_aspawn(really,arglast)
  104. + STR *really;
  105. + int *arglast;
  106. + {
  107. +     register STR **st = stack->ary_array;
  108. +     register int sp = arglast[1];
  109. +     register int items = arglast[2] - sp;
  110. +     register char **a;
  111. +     char **argv;
  112. +     char *tmps;
  113. +     int status;
  114. +     if (items) {
  115. +     New(1101,argv, items+1, char*);
  116. +     a = argv;
  117. +     for (st += ++sp; items > 0; items--,st++) {
  118. +         if (*st)
  119. +         *a++ = str_get(*st);
  120. +         else
  121. +         *a++ = "";
  122. +     }
  123. +     *a = Nullch;
  124. +     if (really && *(tmps = str_get(really)))
  125. +         status = swap_spawn(mksargs, tmps,argv);
  126. +     else
  127. +         status = swap_spawn(mksargs, argv[0], argv);
  128. +     Safefree(argv);
  129. +     }
  130. +     return unix_status(status);
  131. + }
  132. + int
  133. + do_spawn(char *cmd)
  134. + {
  135. +     register char **a;
  136. +     register char *s;
  137. +     char **argv;
  138. +     char flags[10];
  139. +     int status;
  140. +     char *cmd2;
  141. +     char *sh_argv[4];
  142. +     lookat_env();
  143. +     /* see if there are shell metacharacters in it */
  144. +     if (strcspn(cmd, metas) != strlen(cmd)) {
  145. +         sh_argv[0] = shell;        /* sh.exe, command.com, or whatever */
  146. +         sh_argv[1] = slashc;    /* -c or /c or whatever */
  147. +         sh_argv[2] = cmd;        /* command line as supplied */
  148. +         sh_argv[3] = NULL;
  149. +       doshell:
  150. +         return unix_status(swap_spawn(mksargs, shell, sh_argv));
  151. +     }
  152. +     New(1102,argv, strlen(cmd) / 2 + 2, char*);
  153. +     New(1103,cmd2, strlen(cmd) + 1, char);
  154. +     strcpy(cmd2, cmd);
  155. +     a = argv;
  156. +     for (s = cmd2; *s;) {
  157. +     while (*s && isspace(*s)) s++;
  158. +     if (*s)
  159. +         *(a++) = s;
  160. +     while (*s && !isspace(*s)) s++;
  161. +     if (*s)
  162. +         *s++ = '\0';
  163. +     }
  164. +     *a = Nullch;
  165. +     if (argv[0]) {
  166. +     status = swap_spawn(mksargs, argv[0], argv);
  167. +     Safefree(cmd2);
  168. +     Safefree(argv);
  169. +     switch (status) {
  170. +         case -2:
  171. +         sh_argv[0] = comspec;      /* command.com or whatever */
  172. +         sh_argv[1] = com_slashc;  /* -c or /c or whatever */
  173. +         sh_argv[2] = cmd;      /* command line as supplied */
  174. +         sh_argv[3] = NULL;
  175. +         goto doshell;
  176. +         case -3:
  177. +             sh_argv[0] = shell;    /* shell script */
  178. +         sh_argv[1] = cmd;    /* command line as supplied */
  179. +         sh_argv[2] = NULL;
  180. +         goto doshell;
  181. +     }
  182. +     status = unix_status(status);
  183. +     }
  184. +     return status;
  185. + }
  186. + /* Convert status as returned by MS-DOS int 21h, function 4dh call
  187. +    to the unix wait(2) style expected by perl.
  188. + */
  189. + static unsigned short unix_status(unsigned short dos_status)
  190. + {
  191. +     unsigned short result;
  192. +     switch (dos_status & 0xFF00) {
  193. +         case 0xFF00:        /* didn't find the program to run */
  194. +         result = 0xFF00;    /* simulate child doing _exit(-1) */
  195. +         break;
  196. +         case 0x100:        /* control break exit */
  197. +         result = SIGINT;    /* child saw SIGINT */
  198. +         raise(SIGINT);    /* keyboard signal to parent, too */
  199. +         break;
  200. +     default:        /* undefined */
  201. +     case 0x200:        /* critical error death */
  202. +         result = SIGABRT;
  203. +         break;
  204. +     case 0x300:        /* TSR exit! */
  205. +     case 0:            /* child ran to completion */
  206. +         result = dos_status << 8;    /* DOS uses low byte, unix high */
  207. +         break;
  208. +     }
  209. +     return result;
  210. + }
  211.